using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace Acms.WebControls
{
    public abstract class BaseDataField : DataControlField
    {
        public bool ReadOnly { get; set; }

        private bool required;
        public bool Required
        {
            get { return required; }
            set { required = value; }
        }

        private string requiredMessage;
        public string RequiredMessage
        {
            get { return requiredMessage; }
            set { requiredMessage = value; }
        }

        private ValidatorDisplay requiredDisplay = ValidatorDisplay.Dynamic;
        public ValidatorDisplay RequiredDisplay
        {
            get { return requiredDisplay; }
            set { requiredDisplay = value; }
        }

        private string requiredValidationGroup;
        public string RequiredValidationGroup
        {
            get { return requiredValidationGroup; }
            set { requiredValidationGroup = value; }
        }

        private string dataField;
        public string DataField
        {
            get { return dataField; }
            set { dataField = value; }
        }

        private string dataFormatString;
        public string DataFormatString
        {
            get { return dataFormatString; }
            set { dataFormatString = value; }
        }

        public string HelpText { get; set; }

        protected override object SaveViewState()
        {
            ViewState["ReadOnly"] = ReadOnly;
            ViewState["DataFormatString"] = DataFormatString;
            ViewState["HelpText"] = HelpText;
            return base.SaveViewState();
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
            if (ViewState["ReadOnly"] is bool)
            {
                ReadOnly = (bool)ViewState["ReadOnly"];
            }
            DataFormatString = ViewState["DataFormatString"] as string;
            HelpText = ViewState["HelpText"] as string;
        }

        private int fieldIndex = -1;
        protected int FieldIndex
        {
            get
            {
                if (fieldIndex < 0)
                {
                    DataControlFieldCollection fields = null;
                    if (this.Control is GridView)
                    {
                        fields = ((GridView)this.Control).Columns;
                    }
                    else if (this.Control is DetailsView)
                    {
                        fields = ((DetailsView)this.Control).Fields;
                    }
                    else
                    {
                        throw new NotImplementedException(string.Format("Control of type '{0}' not handeled please do so....", this.Control.GetType().ToString()));
                    }

                    if (fields != null)
                    {
                        fieldIndex = fields.IndexOf(this);
                    }
                }
                return fieldIndex;
            }
        }

        public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
        {
            base.InitializeCell(cell, cellType, rowState, rowIndex);
            if (cellType == DataControlCellType.DataCell)
            {
                if (!ReadOnly && (rowState & DataControlRowState.Edit) != 0 ||
                    (rowState & DataControlRowState.Insert) != 0)
                {
                    InitEditControls(cell, cellType, rowState, rowIndex);
                    InitValidators(cell, cellType, rowState, rowIndex);
                    cell.DataBinding += new EventHandler(editCell_DataBinding);
                }
                else
                {
                    InitDisplayControls(cell, cellType, rowState, rowIndex);
                    cell.DataBinding += new EventHandler(displayCell_DataBinding);
                }
            }
            else if (cellType == DataControlCellType.Header && !string.IsNullOrEmpty(HeaderText))
            {

                string helpIcon = null;
                if (!string.IsNullOrEmpty(HelpText))
                {
                    helpIcon = string.Format(@"<a title=""Help*{0}"" class=""infoPopUp""></a>", System.Web.HttpUtility.HtmlEncode(HelpText));
                }
                cell.Text = string.Concat(helpIcon, HeaderText);
                /*if (!string.IsNullOrEmpty(HelpText))
                {
                    cell.ToolTip = HelpText;
                }*/
            }
            else if (cellType == DataControlCellType.Footer && !string.IsNullOrEmpty(FooterText))
            {
                cell.Text = FooterText;
            }
        }

        void editCell_DataBinding(object sender, EventArgs e)
        {
            DataControlFieldCell cell = sender as DataControlFieldCell;
            IDataItemContainer container = GetDataItemContainer(cell);
            if (cell != null && container != null)
            {
                DataBindEditControls(cell, container.DataItem, container.DataItemIndex, container.DisplayIndex);
            }
        }

        protected virtual void DataBindEditControls(DataControlFieldCell cell, object dataItem, int dataItemIndex, int displayIndex)
        {
        }

        protected virtual void InitEditControls(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
        {
        }

        private void InitValidators(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
        {
            if (Required && cell.Controls.Count > 0)
            {

                RequiredFieldValidator val = new RequiredFieldValidator();
                val.ControlToValidate = cell.Controls[0].ID;
                val.Display = RequiredDisplay;
                if (!string.IsNullOrEmpty(RequiredMessage))
                {
                    val.ErrorMessage = RequiredMessage;
                }
                else
                {
                    val.ErrorMessage = "*Required";
                }
                if (!string.IsNullOrEmpty(RequiredValidationGroup))
                {
                    val.ValidationGroup = RequiredValidationGroup;
                }

                cell.Controls.Add(val);
            }
        }

        protected virtual void InitDisplayControls(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
        {
            Label lbl = new Label();
            cell.Controls.Add(lbl);
        }

        void displayCell_DataBinding(object sender, EventArgs e)
        {
            DataControlFieldCell cell = sender as DataControlFieldCell;
            IDataItemContainer container = GetDataItemContainer(cell);
            if (cell != null && container != null)
            {
                DataBindDisplayControls(cell, container.DataItem, container.DataItemIndex, container.DisplayIndex);
            }
        }

        protected virtual void DataBindDisplayControls(DataControlFieldCell cell, object dataItem, int dataItemIndex, int displayIndex)
        {
            if (cell.Controls.Count > 0)
            {
                Label lbl = cell.Controls[0] as Label;
                IDataItemContainer container = GetDataItemContainer(lbl);
                if (lbl != null && container != null)
                {
                    object val = DataBinder.Eval(container.DataItem, DataField);
                    if (val != null)
                    {
                        if (string.IsNullOrEmpty(dataFormatString))
                        {
                            lbl.Text = val.ToString();
                        }
                        else
                        {
                            lbl.Text = string.Format(dataFormatString, val);
                        }
                    }
                }
            }
        }

        private IDataItemContainer GetDataItemContainer(Control control)
        {
            IDataItemContainer container = null;
            Control current = control;
            while (container == null && current != null && current.NamingContainer != null)
            {
                current = current.NamingContainer;
                container = current as IDataItemContainer;
            }
            return container;
        }

        protected string GetUniqueId(int rowIndex, string id)
        {
            return string.Concat(rowIndex, "_", FieldIndex, "_", id);
        }
    }

}
